package org.budo.java.agent.filter.impl;

import java.lang.reflect.Method;

import org.budo.java.agent.AgentInvoker;
import org.budo.java.agent.filter.AgentFilter;
import org.budo.java.agent.filter.AgentFilterChain;
import org.budo.java.agent.filter.RuntimeAgentFilterChain;

/**
 * @author lmw
 */
public class RuntimeAgentFilterChainImpl implements RuntimeAgentFilterChain {
    private Class<?> targetType;

    private Object target;

    private Integer methodIndex;

    private Object[] args;

    private AgentFilter[] filters;

    private Object result;

    private Integer filterIndex = 0;

    public RuntimeAgentFilterChainImpl(Class<?> targetType, Integer methodIndex, Object target, Object[] args, AgentFilter[] filters) {
        this.targetType = targetType;
        this.methodIndex = methodIndex;
        this.target = target;
        this.args = args;
        this.filters = filters;
    }

    @Override
    public AgentFilterChain doFilter() {
        if (null == filters || filterIndex >= filters.length) {
            ((AgentInvoker) this.target).invoke(this);
        } else {
            filters[filterIndex++].doFilter(this);
        }
        return this;
    }

    @Override
    public Object getResult() {
        return this.result;
    }

    @Override
    public void setResult(Object result) {
        this.result = result;
    }

    @Override
    public Object[] getArgs() {
        return this.args;
    }

    @Override
    public void setArgs(Object[] args) {
        this.args = args;
    }

    @Override
    public Object getTarget() {
        return this.target;
    }

    @Override
    public void setTarget(Object target) {
        this.target = target;
    }

    @Override
    public Integer getFilterIndex() {
        return this.filterIndex;
    }

    @Override
    public AgentFilter[] getFilters() {
        return this.filters;
    }

    public int getMethodIndex() {
        return this.methodIndex;
    }

    @Override
    public Method getMethod() {
        return null;
    }

    @Override
    public Class<?> getTargetType() {
        return this.targetType;
    }
}